package com.cet.qz.unit01.chapter1_1;

import java.security.InvalidParameterException;

/**
 * @program: algorithm
 * @description:
 * @author: 陈恩涛
 * @create: 2020-12-21 21:57
 **/
public class Matrix {

    /*
     *方法描述： 向量点乘
     *
     * @param x
     * @param y
     * @return double
     * @author chenentao
     * @date 2020/12/21 22:06
     */
    public static double dot(double[] x,double[] y) {
        if(x.length == 0 || y.length == 0){
            return 0.0;
        } else if (x.length != y.length) {
           throw new InvalidParameterException("作为因子的两个向量维度不相等！");
        } else {
            int len = x.length;
            double sum = 0.0;
            for (int i = 0; i < len; i++) {
                sum = x[i] * y[i] + sum;
            }
            return sum;
        }
    }

    /*
     *方法描述： 矩阵乘法
     *
     * @param a
     * @param b
     * @return double[][]
     * @author chenentao
     * @date 2020/12/22 21:13
     */
    public static double[][] mult(double[][] a,double[][] b) {
        if(a[0].length != b.length)
            throw  new InvalidParameterException("作为因子的矩阵不合法！");
        else {
            int m = a.length;
            int n = b.length;
            int s = b[0].length;
            double[][] result = new double[m][s];

            for (int i = 0; i < m; i++) {
                for (int j = 0; j < s; j++) {
                    double sum = 0.0;
                    for (int k = 0; k < n; k++) {
                        sum = sum + a[i][k] * b[k][j];
                    }
                    result[i][j] = sum;
                }
            }
            return result;
        }
    }

    /*
     *方法描述：矩阵的转置
     *
     * @param a
     * @return double[][]
     * @author chenentao
     * @date 2020/12/22 21:18
     */
    public static double[][] transpose(double[][] a){
        int m = a.length;
        int n = a[0].length;
        double[][] result = new double[n][m];

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                result[j][i] = a[i][j];
            }
        }
        return result;
    }

    /*
     *方法描述： 矩阵和向量之积，这里是A*(b1,b2,b3...bn)T
     *
     * @param a
     * @param b
     * @return double[][]
     * @author chenentao
     * @date 2020/12/22 21:27
     */
    public static double[][] mult(double[][] a,double[] b){

        double[][] c = new double[b.length][1];
        for (int i = 0; i < b.length; i++) {
            c[i][0] = b[i];
        }
        return mult(a,c);
    }

    /*
     *方法描述： 向量和矩阵之积，这里是(a1,a2,a3...an)*B
     *
     * @param a
     * @param b
     * @return double[][]
     * @author chenentao
     * @date 2020/12/22 21:42
     */
    public static double[][] mult(double[] a,double[][] b) {
        double[][] c = new double[1][a.length];
        for (int i = 0; i < a.length; i++) {
            c[0][i] = a[i];
        }
        return mult(c,b);
    }

    public static void main(String[] args) {
        double[] x = {2,3,4};
        double[] y = {1,2,7};
        double dotResult = dot(x, y);
        System.out.println(dotResult);
        System.out.println("================================");

        double[][] A = {{1,2,3},{4,5,6}};
        double[][] B = {{1,2},{3,4},{5,6}};
        double[][] multResult = mult(A, B);
        for (double[] doubles : multResult) {
            for (double v : doubles) {
                System.out.print(v + "\t");
            }
            System.out.print("\n");
        }
        System.out.println("================================");

        double[][] transposeResult = transpose(A);
        for (double[] doubles : transposeResult) {
            for (double v : doubles) {
                System.out.print(v+"\t");
            }
            System.out.print("\n");
        }
        System.out.println("================================");

        double[][] mult1 = mult(A, x);
        for (double[] doubles : mult1) {
            for (double v : doubles) {
                System.out.print(v+"\t");
            }
            System.out.print("\n");
        }
        System.out.println("================================");

        double[][] mult2 = mult(x, B);
        for (double[] doubles : mult2) {
            for (double v : doubles) {
                System.out.print(v+"\t");
            }
            System.out.print("\n");
        }
    }
}
